﻿using PhotoGallery.Data.Entity;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Xml.Linq;

namespace PhotoGallery.Data.Repository
{
    public class AlbumRepository : BaseRepository
    {
        string fileName;
        string path;
        XDocument doc;
        List<Album> albums = new List<Album>(); 

        public AlbumRepository(string owner)
        {
            Owner = owner;
            path = BasePath + Settings.UploadsFolder + Owner + "\\";
            fileName = path + AlbumsXml;            
            LoadData(fileName);
        }        

        public IEnumerable<Album> Get()
        {                       
            return albums;
        }

        public Entity.Album Get(int id)
        {
            return albums.FirstOrDefault(a => a.ID == id); 
        }

        public int Create(Album album)
        {
            if (!String.IsNullOrEmpty(album.FolderName) && Directory.Exists(path + "Photos\\"))
            {
                string[] folders = Directory.GetDirectories(path + "Photos\\", album.FolderName + "*");
                if (folders.Length > 0)
                {
                    album.FolderName += "(" + folders.Length + ")";
                }
            }

            // add album
            album.ID = GetMaxValue()+1;
            album.CreatedOn = DateTime.UtcNow;
            albums.Add(album);

            XElement xml = new XElement("albums",
            from i in albums
            orderby album.ID
            select new XElement("album",
                      new XElement("id", i.ID),
                      new XElement("title", i.Title ?? ""),
                      new XElement("folderName", i.FolderName ?? ""),
                      new XElement("filename", i.FileName ?? ""),
                      new XElement("createdOn", ConvertDate(album.CreatedOn)),
                      new XElement("modifiedOn", null),
                      new XElement("deletedOn", null),
                      new XElement("shared", i.Shared),
                      new XElement("orderNumber", GetMaxOrderNumber() + 1),
                      new XElement("active", true)
                      )
            );

            CreateAlbum(getAlbumFolder( album));

            // finaly 
            doc = new XDocument(xml);
            doc.Save(fileName);

            return album.ID;
        }

        public void Update(Album album)
        {
            XElement node = doc.Root.Elements("album").Where(i => (int)i.Element("id") == album.ID).FirstOrDefault();

            node.SetElementValue("id", album.ID);
            node.SetElementValue("title", album.Title ?? "");
            node.SetElementValue("filename", album.FileName ?? "");
            node.SetElementValue("modifiedOn", ConvertDate(album.ModifiedOn) ?? ConvertDate(DateTime.UtcNow));
            node.SetElementValue("shared", (int) album.Shared);
            doc.Save(fileName);

            PublicAlbumRepository p = new PublicAlbumRepository();
            string albumFolder = String.IsNullOrEmpty(album.FolderName)  ? "album"+album.ID : album.FolderName;
            if (album.Shared == SharedAlbum.Public || album.Shared == SharedAlbum.AllUsers)
            {
                var a = p.GetByOwner(Owner,albumFolder);
                if (a == null)
                {
                    p.Create(new PublicAlbum() { Owner = Owner, FolderName = albumFolder, FileName = album.FileName, Title = album.Title, Shared = album.Shared });
                }
                else
                {
                    a.Shared = album.Shared;
                    p.Update(a);
                }
            }
            else if (album.Shared == SharedAlbum.Private)
            {
                var a = p.GetByOwner(Owner, albumFolder);
                if (a != null)
                {
                    p.Delete(a.ID);
                }
            }
            
        }

        public void Delete(Album album)
        {
            album.DeletedOn = DateTime.UtcNow;
            XElement node = doc.Root.Elements("album").Where(i => (int)i.Element("id") == album.ID).FirstOrDefault();

            node.SetElementValue("deletedOn", ConvertDate(album.DeletedOn));
            node.SetElementValue("active", false);

            doc.Save(fileName);
        }

        public int Erise(int id)
        {
            doc.Root.Elements("album").Where(i => (int)i.Element("id") == id).Remove();
            doc.Save(fileName);
            return 1;
        }

        #region privateMethods

        private int GetMaxValue()
        {
            int count = doc.Descendants("album").Count();
            if (count > 0)
            {
                var maxID = (from prod in doc.Descendants("album")
                             select
                             (
                                         int.Parse(prod.Element("id").Value)
                             )).Max();

                return maxID;
            }
            else
            {
                return 0;
            }
        }

        private int GetMaxOrderNumber()
        {
            int count = doc.Descendants("album").Count();
            if (count > 0)
            {
                var maxID = (from prod in doc.Descendants("album")
                             select
                             (
                                         int.Parse(prod.Element("orderNumber").Value)
                             )).Max();

                return maxID;
            }
            else
            {
                return 0;
            }
        }

        private void LoadData(string fileName)
        {
            if (File.Exists(fileName))
            {
                doc = XDocument.Load(fileName);
            }
            else
            {
                doc =
                  new XDocument(
                    new XElement("albums")
                    );
                doc.Save(fileName);
            }

            int count = doc.Descendants("album").Count();
            if (count > 0)
            {

                var q = from album in doc.Descendants("album")
                        select new Album(
                                        Convert.ToInt32(album.Element("id").Value),
                                        album.Element("title").Value,
                                        album.Element("folderName").Value,
                                        album.Element("filename").Value,
                                        ConvertDate(album.Element("createdOn").Value),
                                        ConvertDate(album.Element("modifiedOn").Value),
                                        ConvertDate(album.Element("deletedOn").Value),
                                        (SharedAlbum)Enum.Parse(typeof(SharedAlbum), album.Element("shared").Value),
                                        Convert.ToInt32(album.Element("orderNumber").Value),
                                        album.Element("active").Value == "false" ? false : true
                                        );
                albums.AddRange(q.Where(x=>x.Active == true).OrderByDescending(x => x.ID).ToList<Album>());
            }
        }

        private void CreateAlbum(string albumFolder)
        {
            // Create image folder
            string imageFolder = path + "Images\\" + albumFolder;
            System.IO.Directory.CreateDirectory(imageFolder);

            // Create photo folder
            string photoFolder = path + "Photos\\" + albumFolder;
            System.IO.Directory.CreateDirectory(photoFolder);
            string photoMetaData = photoFolder + "\\" + Settings.PhotoMetaDataXml;
            XDocument photo =
                  new XDocument(
                    new XElement("images")
                    );
            photo.Save(photoMetaData);
                        

            // Create video folder
            string videoFolder = path + "Videos\\" + albumFolder;
            System.IO.Directory.CreateDirectory(videoFolder);
            
            XDocument video =
                  new XDocument(
                    new XElement("videos")
                    );
            video.Save(videoFolder + "\\" + Settings.VideoMetaDataXml);

            XDocument videoAttachments =
                  new XDocument(
                    new XElement("videos")
                    );
            video.Save(videoFolder + "\\" + Settings.VideoAttachmentsMetaDataXml);
            
            // Create audio folder
            string audioFolder = path + "Audio\\" + albumFolder;
            System.IO.Directory.CreateDirectory(audioFolder);
            //source = BasePath + SystemFolder + AudioMetaDataXml;
            string audioMetaData = audioFolder + "\\" + Settings.AudioMetaDataXml;
            XDocument audio =
                  new XDocument(
                    new XElement("audio_list")
                    );
            audio.Save(audioMetaData);
            //System.IO.File.Copy(source, dest, true);
        }
        
        #endregion
    }
}